package ru.averta.notes.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Transactional;
import ru.averta.notes.dao.GenericDao;
import ru.averta.notes.domain.abstr.BusinessObject;
import ru.averta.notes.service.BusinessObjectService;

import javax.annotation.PostConstruct;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;

@Transactional
public abstract class GenericBusinessObjectService<T extends BusinessObject, PK extends Serializable, D extends GenericDao<T, PK>> implements
        BusinessObjectService<T, PK> {

    Logger logger = LoggerFactory.getLogger(GenericBusinessObjectService.class);

    //@Autowired //Autowired не работает с Generic =(. Решаем проблему через @PostConstruct
    protected D dao;

    @Autowired
    private ApplicationContext ctx;

    @PostConstruct
    public void setUp() {
        dao = ctx.getBean(getDaoClass());
    }

    public T create(T newInstance) {
        dao.create(newInstance);
        return newInstance;
    }

    public T findByID(PK id) {
        return dao.findByID(id);
    }

    public Collection<T> findAll() {
        return dao.findAll();
    }

    public void save(T transientObject) {
        dao.save(transientObject);
    }

    public void remove(T object) {
        dao.remove(object);
    }

    @SuppressWarnings("unchecked")
    private Class<D> getDaoClass() {
        ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass();
        return (Class<D>) thisType.getActualTypeArguments()[2];
    }

}
